#include "Channel.h"
#include "Epoller.h"
#include "EventLoop.h"
#include "Logger.h"

Channel::Channel(int fd, EventLoop* loop) : fd_(fd), loop_(loop), events_(0), revents_(0), state_(-1) {}

void Channel::SetReadCallback(const callback cb) {
    read_callback_ = std::move(cb);
}
void Channel::SetWriteCallback(const callback cb) {
    write_callback_ = std::move(cb);
}
void Channel::SetCloseCallback(const callback cb) {
    close_callback_ = std::move(cb);
}
void Channel::SetErrorCallback(const callback cb) {
    error_callback_ = std::move(cb);
}

void Channel::SetRevents(uint64_t revents) {
    revents_ = revents;
}
void Channel::SetState(const int state) {
    state_ = state;
}

// EPOLLIN / EPOLLOUT
// 是否可读写
bool Channel::ReadAble() {
    return events_ & EPOLLIN;
}
bool Channel::WriteAble() {
    return events_ & EPOLLOUT;
}

// 打开可读写
void Channel::EnableRead() {
    LOG_INFO("sock: %d sets readable...", fd_);
    events_ |= EPOLLIN;
    Update();
}
void Channel::EnableWrite() {
    events_ |= EPOLLOUT;
    Update();
}

// 关闭可读写
void Channel::DisableRead() {
    events_ &= ~EPOLLIN;
    Update();
}
void Channel::DisableWrite() {
    events_ &= ~EPOLLOUT;
    Update();
}
void Channel::DisableAll() {
    events_ = 0;
    Update();
}

void Channel::Update() {
    // epoll:epoll_ctl(),不能直接调用epoll,通过loop来调用
    loop_->UpdateChannel(this);
}

// loop中删除当前channel
void Channel::Remove() {
    loop_->RemoveChannel(this);
}

void Channel::HandleEvent() {
    // 分发事件
    if ((events_ & EPOLLHUP) || (events_ & EPOLLERR) && error_callback_) {
        error_callback_();
    } else if ((events_ & EPOLLIN) && read_callback_) {
        LOG_INFO("readcallback...");
        read_callback_();
    } else if ((events_ & EPOLLOUT) && write_callback_) {
        write_callback_();
    } else
        close_callback_();
}

int Channel::Fd() {
    return fd_;
}
uint32_t Channel::Events() {
    return events_;
}
EventLoop* Channel::OwnerLoop() {
    return loop_;
}
int Channel::State() {
    return state_;
}

Channel::~Channel() {}
